package chapter7;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author caiya
 * @date 2020/3/31 22:03
 * @description
 */
@Slf4j
public class CyclicBarrierTest {
    /**
     * CyclicBarrier：回旋屏障类，让一组线程全部达到一种状态后再全部同时执行
     * 1、调用await方法的线程会被阻塞，阻塞点称为屏障点
     * 2、等所有线程都调用了await方法后，线程们就会冲破屏障点，继续向下执行
     * 3、和CountDownLatch比较：CyclicBarrier的计数器可以被重置
     * 4、所有线程达到冲破屏障后，执行CyclicBarrier的任务，而后各个线程继续执行执行
     */

    // demo效果：2个线程将各自任务执行完毕后再执行汇总（回调）线程

    static volatile CyclicBarrier cyclicBarrier = new CyclicBarrier(2, new Runnable() {
        @Override
        public void run() {
            log.debug(Thread.currentThread().getName() + "【CyclicBarrier 回调执行!!!】");
        }
    });
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(2);

        for (int i = 0; i < 2; i++) {
            executorService.submit(new Runnable() {
                @Override
                public void run() {
                    log.debug(Thread.currentThread().getName() + "【达到屏障点】");
                    try {
                        cyclicBarrier.await();
                        log.debug(Thread.currentThread().getName() + "【冲破屏障点后执行】");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }

        log.debug(Thread.currentThread().getName() + "【运行中1】");
        executorService.shutdown();
        log.debug(Thread.currentThread().getName() + "【运行中2】");
    }


}
